home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
ole2book.zip
/
CHAP06.ZIP
/
CHAP06
/
EDATAOBJ
/
DATAOBJ.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-14
|
8KB
|
340 lines
/*
* DATAOBJ.CPP
* Data Object for Chapter 6
*
* Implementation of the CDataObject and CImpIDataObject that work
* in either an EXE or DLL.
*
* Copyright (c)1993 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Software Design Engineer
* Microsoft Systems Developer Relations
*
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "dataobj.h"
extern HINSTANCE g_hInst;
DWORD g_dwID=0;
//Names of data sizes
static char * rgszSize[3]={"Small", "Medium", "Large"};
/*
* CDataObject::CDataObject
* CDataObject::~CDataObject
*
* Parameters (Constructor):
* punkOuter LPUNKNOWN of a controlling unknown, if it exists.
* pfnDestroy LPFNDESTROYED to call when an object is destroyed.
* iSize UINT specifying the size of the data set to use.
*/
CDataObject::CDataObject(LPUNKNOWN punkOuter, LPFNDESTROYED pfnDestroy
, UINT iSize)
{
UINT i;
m_cRef=0;
m_punkOuter=punkOuter;
m_pfnDestroy=pfnDestroy;
m_iSize=iSize;
m_hWndAdvise=NULL;
m_dwAdvFlags=ADVF_NODATA;
//NULL any contained interfaces initially.
m_pIDataObject=NULL;
m_pIDataAdviseHolder=NULL;
//Initilize the FORMATETCs arrays we use for ::EnumFormatEtc
m_cfeGet=CFORMATETCGET;
//These macros are in bookguid.h
SETDefFormatEtc(m_rgfeGet[0], CF_METAFILEPICT, TYMED_MFPICT);
SETDefFormatEtc(m_rgfeGet[1], CF_BITMAP, TYMED_GDI);
SETDefFormatEtc(m_rgfeGet[2], CF_TEXT, TYMED_HGLOBAL);
for (i=0; i < DOSIZE_CSIZES; i++)
m_rghBmp[i]=NULL;
return;
}
CDataObject::~CDataObject(void)
{
UINT i;
for (i=0; i < DOSIZE_CSIZES; i++)
{
if (NULL!=m_rghBmp[i])
DeleteObject(m_rghBmp[i]);
}
if (NULL!=m_pIDataAdviseHolder)
m_pIDataAdviseHolder->Release();
if (NULL!=m_pIDataObject)
delete m_pIDataObject;
if (NULL!=m_hWndAdvise)
DestroyWindow(m_hWndAdvise);
return;
}
/*
* CDataObject::FInit
*
* Purpose:
* Performs any intiailization of a CDataObject that's prone to failure
* that we also use internally before exposing the object outside.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the function is successful, FALSE otherwise.
*/
BOOL CDataObject::FInit(void)
{
LPUNKNOWN pIUnknown=(LPUNKNOWN)this;
UINT i;
char szTemp[80];
UINT cy;
if (NULL!=m_punkOuter)
pIUnknown=m_punkOuter;
//Allocate contained interfaces.
m_pIDataObject=new CImpIDataObject(this, pIUnknown);
if (NULL==m_pIDataObject)
return FALSE;
for (i=0; i < DOSIZE_CSIZES; i++)
{
m_rghBmp[i]=LoadBitmap(g_hInst, MAKEINTRESOURCE(i+IDB_MIN));
if (NULL==m_rghBmp[i])
return FALSE;
}
/*
* Register the Advise window class first time through (g_dwID==0)
*/
if (0==g_dwID)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = AdvisorWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(LPCDataObject);
wc.hInstance = g_hInst;
wc.hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDR_ADVISORICON));
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = "Advisor";
if (!RegisterClass(&wc))
return FALSE;
}
/*
* Create an advise window with a unique caption:
* "Data Object Advisor #xx" where xx is counted globally
* every time a CDataObject is created.
*/
g_dwID++;
#ifdef EXEDATAOBJECT
wsprintf(szTemp, "%s EXE Advisor #%lu", (LPSTR)rgszSize[m_iSize], g_dwID);
#else
wsprintf(szTemp, "%s DLL Advisor #%lu", (LPSTR)rgszSize[m_iSize], g_dwID);
#endif
cy=(GetSystemMetrics(SM_CYBORDER)*2)+GetSystemMetrics(SM_CYMENU)
+ GetSystemMetrics(SM_CYCAPTION);
m_hWndAdvise=CreateWindow("Advisor", szTemp
, WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER | WS_VISIBLE
, CW_USEDEFAULT, CW_USEDEFAULT, 200, cy, HWND_DESKTOP
, NULL, g_hInst, this);
if (NULL==m_hWndAdvise)
return FALSE;
return TRUE;
}
/*
* CDataObject::QueryInterface
* CDataObject::AddRef
* CDataObject::Release
*
* Purpose:
* IUnknown members for CDataObject object.
*/
STDMETHODIMP CDataObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv=NULL;
if (IsEqualIID(riid, IID_IUnknown))
*ppv=(LPVOID)this;
if (IsEqualIID(riid, IID_IDataObject))
*ppv=(LPVOID)m_pIDataObject;
//AddRef any interface we'll return.
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CDataObject::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CDataObject::Release(void)
{
ULONG cRefT;
cRefT=--m_cRef;
if (0==m_cRef)
{
/*
* Tell the housing that an object is going away so it can
* shut down if appropriate.
*/
if (NULL!=m_pfnDestroy)
(*m_pfnDestroy)();
delete this;
}
return cRefT;
}
/*
* AdvisorWndProc
*
* Purpose:
* Standard window class procedure.
*/
LRESULT FAR PASCAL __export AdvisorWndProc(HWND hWnd, UINT iMsg
, WPARAM wParam, LPARAM lParam)
{
LPCDataObject pDO;
DWORD i;
DWORD iAdvise;
DWORD dwTime;
DWORD dwAvg;
char szTime[128];
char szTitle[80];
HCURSOR hCur, hCurT;
//This will be valid for all messages except WM_NCCREATE
pDO=(LPCDataObject)GetWindowLong(hWnd, 0);
switch (iMsg)
{
case WM_NCCREATE:
pDO=(LPCDataObject)((LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
SetWindowLong(hWnd, 0, (LONG)pDO);
return (DefWindowProc(hWnd, iMsg, wParam, lParam));
case WM_CLOSE:
//Eat to forbid task manager from closing us.
return 0L;
case WM_COMMAND:
if (NULL==pDO->m_pIDataAdviseHolder)
break;
//Send IAdviseSink::OnDataChange many times.
i=(DWORD)(LOWORD(wParam)-IDM_ADVISEITERATIONSMIN+1);
iAdvise=(i*i)*16;
hCur=LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
hCurT=SetCursor(hCur);
ShowCursor(TRUE);
dwTime=GetTickCount();
i=0;
while (TRUE)
{
#ifdef EXEDATAOBJECT
#ifndef WIN32
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
#endif
#endif
{
pDO->m_pIDataAdviseHolder->SendOnDataChange(
pDO->m_pIDataObject, 0, ADVF_NODATA);
if (++i >= iAdvise)
break;
}
}
dwTime=GetTickCount()-dwTime;
dwAvg=dwTime/iAdvise;
SetCursor(hCurT);
ShowCursor(FALSE);
wsprintf(szTime, "Total\t=%lu milliseconds\n\rAverage\t=%lu milliseconds"
, dwTime, dwAvg);
GetWindowText(hWnd, szTitle, sizeof(szTitle));
MessageBox(hWnd, szTime, szTitle, MB_OK);
break;
default:
return (DefWindowProc(hWnd, iMsg, wParam, lParam));
}
return 0L;
}